package com.ac.config;

import com.base.annotation.DataDecrypt;
import com.base.helper.AesCrypt;
import com.base.helper.ClazzUtils;
import com.base.helper.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @Author mzl.
 */
@Aspect
@Component
public class DataDecryptAspect {

    private Logger logger = LoggerFactory.getLogger(DataDecryptAspect.class);

    private ThreadLocal<Long> startTime = new ThreadLocal<>();


    @Pointcut("execution(public * com.ac.api.*.service.impl.*.*(..))")
    public void dataDecrypt() {
    }

    @AfterReturning(returning = "data", pointcut = "dataDecrypt()")
    public void doAfterReturning(JoinPoint joinPoint, Object data) throws Throwable {
        /** 处理完请求，返回内容 */
        logger.info("RESPONSE : " + data);
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method          targetMethod    = methodSignature.getMethod();
        DataDecrypt     dataDecrypt     = targetMethod.getAnnotation(DataDecrypt.class);
        if(null==dataDecrypt){
            return ;
        }
        String keyStr=dataDecrypt.params();
        if(StringUtils.isEmpty(keyStr)){
            return ;
        }
        List<String> keys       = Arrays.asList(keyStr.split(","));
        Object object=data;
        if(object instanceof List){
            List list=(List)object;
            for (Object o : list) {
                decrype(o,keys);
            }
        }else{
            decrype(object,keys);
        }
    }

    /**
     * 解密
     * @param o
     * @param keys
     */
    private void decrype(Object o,List<String> keys){
        String[]     fieldNames = ClazzUtils.getFiledName(o);
        for (String fieldName : fieldNames) {
            if(keys.indexOf(fieldName)<0) {
                continue;
            }
            String value = (String)ClazzUtils.getFieldValueByName(fieldName,o);
            if(StringUtils.isNotEmpty(value)){
                value = AesCrypt.aesDecrypt(value);
                ClazzUtils.setFieldValueByName(fieldName,o,value);
            }
        }
    }

}
